<?php
/**
 * Created by PhpStorm.
 * Author: ls
 * Time: 2023/9/28 11:57
 * Desc: 微信快速登录
 */

class Service_Api_Member_WxClient extends Contract_Api_Member_WxClient
{

    public function login(array $params): array
    {
        require_once BASEPATH . 'plugins/api/vendor/api/weixin.class.php';

        /**
         * @var $mid
         */
        extract($params);

        // 已登录状态
        if ($mid) {
            // 检查是否绑定微信
            $member_third = DB::select()
                ->from('member_third')
                ->join('member', 'inner')
                ->on('member.mid', '=', 'member_third.mid')
                ->where('member_third.mid', '=', $mid)
                ->where('member_third.wx_openid', '!=', '')
                ->where('member.mobile', '!=', '')
                ->execute()
                ->current();
            if ($member_third) {
                throw new Exception(__("已绑定微信且正常登录"));
            }
        }

        $config = $this->get_conf();

        if ($config['appid'] && $config['appkey']) {
            // 判断是否开启微信快速登录
            $state  = 'wxclientlogin';
            $author = new weixinPHP($config['appid'], $config['appkey'], $config['callback'], $state);
            $url    = $author->login_url();
            return array('url' => $url);
        } else {
            throw new Exception("微信快速登录参数配置有误");
        }
    }

    public function callback($params): array
    {
        require_once BASEPATH . 'plugins/api/vendor/api/weixin.class.php';

        /**
         * @var $code
         * @var $mid
         */
        extract($params);

        $fxpcode = Arr::get($params, 'fxpcode', '');

        $user = array();

        $config = $this->get_conf();
        $author = new weixinPHP($config['appid'], $config['appkey'], $config['callback'], time());

        $token_arr = $author->access_token($code);
        if (!isset($token_arr['openid']) || !isset($token_arr['access_token'])) {
            St_Log::write('获取Openid失败', [$token_arr], 'api/wxclient/log');
            $err_msg = $token_arr['errmsg'] ?? '获取Openid失败';
            throw new Exception($err_msg);
        }

        try {
            $token  = $token_arr['access_token'];
            $openid = $token_arr['openid'];
            $author = $author->get_user_info($openid, $token);

            if (!isset($author['openid'])) {
                $data = array(
                    'errCode' => 1,
                    'author' => $author
                );
                throw new Exception('获取用户信息失败');
            }

            $author['unionid'] = $author['unionid'] ?: $author['openid'];
            $user['openid']    = $author['unionid'];
            $user['unionid']   = $author['unionid'];
            $user['nickname']  = $author['nickname'];
            $user['litpic']    = $author['headimgurl'];
            $user['wx_openid'] = $author['openid'];
            $user['come_from'] = 'weixin';

            // 已登录状态
            if ($mid) {
                $user['mid'] = $mid;
                Model_Api_V2_Member_Login::third_login_bind($user);
                // 获取用户登录信息
                $member = Model_Member::get_member_byid($mid);
            } else {
                // 未登录状态
                $member_third = Model_Api_V2_Member_Third::get_member_third_by_wx($author['openid'], $author['unionid']);

                if (!empty($member_third)) {
                    if ($member_third['openid'] != $author['unionid']) {
                        //更新
                        Model_Api_V2_Member_Third::update_redundant_by_unionid($member_third['mid'], $member_third['id'], $author['unionid']);
                    }

                    if (!empty($member_third['nickname'])) {
                        unset($user['nickname']);
                    }

                    //这里补充记录微信公众号的用户openid用于微信公众号的相关应用操作.
                    DB::update('member_third')
                        ->set(array('wx_openid' => $user['wx_openid']))
                        ->where('mid', '=', $member_third['mid'])
                        ->execute();

                    // 检查是否有会员账号
                    $member = Model_Member::get_member_byid($member_third['mid']);
                }

                $add_member = false;

                // 检测用户是否存在, 不存在就去注册新用户
                if(empty($member)) {
                    $third_bind = Model_Api_V2_Member_Login::third_bind(array('third' => $user));
                    // 新增用户
                    if (!$third_bind['bool']) {
                        $data = array(
                            'errCode' => 2,
                            'author' => $author
                        );
                        throw new Exception('用户注册失败');
                    }

                    $add_member = true;

                    // 重新获取用户id
                    $member_third = Model_Api_V2_Member_Third::get_member_third_by_wx($author['openid'], $author['unionid']);
                    $member = Model_Member::get_member_byid($member_third['mid']);
                }

                //用户登录处理
                Model_Api_V2_Member_Login::write_login_info($member_third, $add_member);

                // 检查是否安装分销商应用
                if(!empty($fxpcode)){
                    if (St_Functions::is_normal_app_install('mobiledistribution')) {
                        // 检查是否是分销商
                        $is_fenxiao = DB::select('fxcode', 'status')
                            ->from('fenxiao')
                            ->where('memberid', '=', $member['mid'])
                            ->execute()
                            ->current();
                        if (!$is_fenxiao) { // 不是分销商且分销商fxcode不为空
                            Model_Fenxiao::invite($member['mid'], $fxpcode);
                        }
                    }
                }
            }

            //获取登录配置
            $data = Model_Api_V2_Member_Login::login_init($member);

            $result = array(
                'data' => $data,
                'msg' => '登录成功',
                'status' => true
            );
        } catch (Exception $e) {
            $result = array(
                'msg' => $e->getMessage(),
                'status' => false,
                'data' => $data
            );
        }

        return $result;
    }

    /**
     *  配置第三方登录信息
     * @return string[]
     */
    private function get_conf(): array
    {
        $arr  = DB::select()
            ->from('sysconfig')
            ->where("varname in('cfg_wx_client_appkey','cfg_wx_client_appsecret')")
            ->execute()
            ->as_array();
        $info = array(
            "callback" => Common::get_main_host() . "/h5/"
        );
        foreach ($arr as $v) {
            if ($v['varname'] == 'cfg_wx_client_appkey') {
                $info['appid'] = $v['value'];
            }
            if ($v['varname'] == 'cfg_wx_client_appsecret') {
                $info['appkey'] = $v['value'];
            }
        }
        $config         = Model_Sysconfig::get_configs(0, array('cfg_global_wx_appkey', 'cfg_global_wx_appsecret'));
        $info['appid']  = $config['cfg_global_wx_appkey'] ?: $info['appid'];
        $info['appkey'] = $config['cfg_global_wx_appsecret'] ?: $info['appkey'];

        return $info;
    }
}